/***********************************************\
|	"Warehouse's database, Alexander Yushkov"	|
|	- item.cpp - implementation of functions	|
|		from item.h header.						|
\***********************************************/

#include <cstring>
#include "item.h"

namespace lmf {

Date::Date(int d,int m,int y) : day(d), mounth(m), year(y)
{
	if(year<1900)
		throw int();
    int max_days=0;
    switch(mounth)
    {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            max_days=31;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            max_days=30;
            break;
        case 2:
            max_days=(year-1900)%4?28:29;
            break;
        default:
            throw int();
            break;
    }
    if(day<1 || day>max_days)
        throw int();
    return;
}

bool operator==(const Date& one,const Date& two)
{
	return one.day==two.day && one.mounth==two.mounth && one.year==two.year;
}

bool operator!=(const Date& one,const Date& two)
{
	return one.day!=two.day || one.mounth!=two.mounth || one.year!=two.year;
}

bool operator>(const Date& one,const Date& two)
{
	if(one.year==two.year)
	{
		if(one.mounth==two.mounth)
			return one.day>two.day;
		else
			return one.mounth>two.mounth;
	}
	else
		return one.year>two.year;
}

bool operator<(const Date& one,const Date& two)
{
	if(one.year==two.year)
	{
		if(one.mounth==two.mounth)
			return one.day<two.day;
		else
			return one.mounth<two.mounth;
	}
	else
		return one.year<two.year;
}

bool operator>=(const Date& one,const Date& two)
{
	return !(one<two);
}

bool operator<=(const Date& one,const Date& two)
{
	return !(one>two);
}

Group::Group(Date d,double c,double pb,double ps) : count(c), price_buy(pb), price_sell(ps)
{
    date_in=new Date(d);
    if(!price_sell)
        price_sell=price_buy;
    if(count<1 || price_buy<0 || price_sell<price_buy)
    {
        delete date_in;
        throw int();
    }
    return;
}

Group::Group(const Group& gr) : count(gr.count), price_buy(gr.price_buy), price_sell(gr.price_sell)
{
    date_in=new Date(*(gr.date_in));
    return;
}

Group& Group::operator=(const Group& gr)
{
    *date_in=*(gr.date_in);
    count=gr.count;
    price_buy=gr.price_buy;
    price_sell=gr.price_sell;
    return *this;
}

Group::~Group()
{
    delete date_in;
    return;
}

void serialize(const Group& gr,char* buf)
{
    int offset=0;
    Date* pdate=(Date*)(buf+offset);
        offset+=sizeof(Date);
    double* pcount=(double*)(buf+offset);
        offset+=sizeof(double);
    double* pprice_buy=(double*)(buf+offset);
        offset+=sizeof(double);
    double* pprice_sell=(double*)(buf+offset);
        offset+=sizeof(double);

    *pdate=*gr.date_in;
    *pcount=gr.count;
    *pprice_buy=gr.price_buy;
    *pprice_sell=gr.price_sell;
    return;
}

void serialize(const Record& rec,char* buf)
{
    memmove(buf,&rec,sizeof(rec));
    return;
}

void deserialize(const char* buf,Group& gr)
{
    int offset=0;
    Date* pdate=(Date*)(buf+offset);
        offset+=sizeof(Date);
    double* pcount=(double*)(buf+offset);
        offset+=sizeof(double);
    double* pprice_buy=(double*)(buf+offset);
        offset+=sizeof(double);
    double* pprice_sell=(double*)(buf+offset);
        offset+=sizeof(double);

    *gr.date_in=*pdate;
    gr.count=*pcount;
    gr.price_buy=*pprice_buy;
    gr.price_sell=*pprice_sell;
    return;
}

void deserialize(const char* buf,Record& rec)
{
    memmove(&rec,buf,sizeof(rec));
    return;
}

}
